iT邦幫忙

2026 iThome 鐵人賽

DAY 15
1
Software Development

30天打造一套企業PLM系列 第 15

Day 15:Redline——變更差異比對怎麼做

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20260901/2016129095YEeldh1u.jpg

系列:30 天打造企業級 PLM|面向:全端

問題場景

簽核的人最想知道的只有一件事:這次到底改了什麼?把改前改後兩份完整資料丟給他自己比對,是簽核體驗的謀殺。Redline(紅線標記,源自工程圖紙上用紅筆標改動的概念)要做的就是欄位級、BOM 行級的差異,修改的內容標記出來。今天講差異怎麼存、怎麼呈現。

商業邏輯設計

  • Redline 是決策輔助,不是報表。簽核者要的是改了什麼、影響到誰,五秒內看懂,資訊設計以變更為主角、原始資料當背景
  • 差異紀錄本身是稽核證據,要的不只是現在長怎樣,還有當時改了哪裡、誰改的

技術選型與取捨:存快照還是存增量?

架構演進:Agile 的招牌功能,怎麼在自建系統復現

先把話說在前面:Redline 是 Oracle Agile PLM 的招牌賣點,不是它的弱項。ECO 上的 Redline BOM / Redline AML 是整個變更管理的核心體驗,SDK 也給得很完整——透過 IChange 取得變更單、用 ITableChangeConstants.TABLE_REDLINEBOM 之類的 redline 表,就能逐行讀出這張單相對於原始 BOM 的增刪改;報表面也有現成的變更報表與 BOM 比對輸出。做過 Agile 客製的人都知道,這塊的成熟度是十幾年累積出來的。

所以自建 PLM 在這一章的題目不是「怎麼贏過 Agile」,而是怎麼把這套成熟的變更差異機制,用開放的資料結構重新長出來。差別在哪?Agile 的 redline 是綁在它自己的 schema、授權模型與 UI 上的:差異資料的形狀由產品定義,你能取用,但取用的路徑得走它的 SDK 與物件模型;要把差異送進自家的簽核路由、通知、看板,中間永遠隔著一層轉譯。自建的價值就在把這層轉譯拿掉——差異從第一天就以自己的 JSON 結構落地,誰要用都直接讀。

Mini-PLM 採用增量為主、快照為輔的結構化 JSON Redline 實體設計

/** 動作類型(ADD/UPDATE/REPLACE/REMOVE) */
@Enumerated(EnumType.STRING)
private BomRedlineActionEnum actionType;

/** 目標 BOM 行 ID(UPDATE/REPLACE/REMOVE 必填) */
private Long targetBiId;

/** Change Out(JSON 快照) */
@Type(type = "com.miniplm.config.ClobStringType")
private String changeOutJson;

/** Change In(JSON 快照) */
private String changeInJson;

/** PATCH(JSON;UPDATE/REPLACE 用) */
private String patchJson;

一列 redline 等於一個動作(ADD / UPDATE / REPLACE / REMOVE)加三份 JSON:changeOutJson 是被改掉的那行當時長什麼樣(快照),changeInJson 是改完之後長什麼樣(快照),patchJson 是實際動到的欄位(增量)。

為什麼三份都要?各自服務不同讀者。patch 給差異視覺化,只標動過的欄位;changeOut 可看到何時移出,就算原始 BOM 行後來被別的變更改了,還是能看出當時的樣子;changeIn 紀錄何時加入的。

補一個型別細節:三個 JSON 欄位用自訂 ClobStringType 對映,這是跨 Oracle(CLOB)與 PostgreSQL(text)的大文字欄位處理,Day 27 的伏筆。

核心內容

動作語意:REPLACE 為什麼獨立於 UPDATE

ADD / UPDATE / REMOVE 好懂。REPLACE(換料:A 料換成 B 料,位置與用量不變)看似 UPDATE 的特例,卻獨立成動作,因為業務語意不同:UPDATE 是同一顆料改屬性,REPLACE 是換供應、換件,下游的採購通知、庫存處置完全兩回事。實體上的註解也留了規則:「Find Number:ADD 必填;REPLACE 必須與原行相同」,換料不換位置。diff 的動作分類要按業務語意設計,不是按資料庫操作設計。資料庫視角 REPLACE 就是 UPDATE,業務視角天差地遠。

https://ithelp.ithome.com.tw/upload/images/20260901/20161290GUbuZUa3Cb.png

上圖是實機畫面:同一張變更單的 BOM 上,UPDATE 只把改動的用量標成橘色、REPLACE 上下兩列並排(舊料刪除線、新料綠色,Seq. No 不變)、REMOVE 整列紅色刪除線、沒動到的那列標 No Change 淡出當背景、ADD 整列綠色。合併預覽是 base BOM 疊上 redline actions 算出來的,每一列都能單獨 Undo。

欄位級 diff 與呈現

Item 欄位的 redline 同樣以 pending_data(Day 13)為基準:pending 與 original 逐欄比對,前端呈現三態,新增綠色、修改原值刪除線加新值、移除紅色。實作上有兩條規矩。只標有效差異:null 對空字串、多餘空白這類假差異要在比對前正規化掉,否則簽核者滿眼紅線全是雜訊。多選欄位比集合不比字串:multilist 存 JSON 陣列(Day 4),["A","B"]["B","A"] 是同一個值,字串比對會誤報。

AML redline:架構複用

核可供應商清單(AML)的變更走同一套 redline 架構(FormItemAmlRedline,鏡像 BOM redline 的欄位設計),動作分類、三份 JSON、放行套用全部同款。第二次實作同一個模式時,就值得把模式固定下來:之後任何行級資料的受控變更,例如未來的替代料清單,都有現成骨架。

踩坑記錄

  • redline 批次寫入 5.3 秒。一張大變更單掛幾百條 redline,逐筆 save 的 dirty checking 成本疊加,改 saveAll 批次化後降一個數量級。Day 21 壓測抓出的另一個熱點,跟 Day 14 的 INSERT-SELECT 是同一堂課:ORM 逐筆操作不適合批次場景
  • diff 基準漂移。簽核中來源資料又被別的表單改了,diff 該對掛單時的原版還是現在的原版?答案是掛單時,changeOutJson 快照存在的理由就在這。Mini-PLM 早期版本沒存快照,兩張並行變更單會互相污染對方的差異顯示——這正是 Agile 用 pending revision 鎖定(Day 13)擋掉的問題,換一套架構就得自己補上等價的保護

小結

復現 Agile 的招牌功能,關鍵不在畫面像不像,而在差異資料的結構自己說得清楚:動作加三份 JSON,增量給呈現、快照給稽核與套用;動作分類按業務語意,REPLACE 不等於 UPDATE;假差異在比對前先正規化。差異看得懂之後,下一個問題是怎麼找到我要的東西。明日 Day 16:進階搜尋,條件建構器與幾百個動態欄位的動態查詢。


上一篇
Day 14:BOM 多階展開——後端演算法+前端樹狀表格
下一篇
Day 16:進階搜尋——條件建構器+動態 Predicate
系列文
30天打造一套企業PLM17
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言